<template>
  <div>
    <HelloWorld :predict="predict" />
    <!-- lading的样式 -->
    <div class="loading" v-if="isLoading">
      <div class="spinner"></div>
    </div>
  </div>

</template>

<script setup>
import HelloWorld from './components/HelloWorld.vue'
import { ref, onMounted } from 'vue';
import { AutoModel, AutoProcessor, env, RawImage } from '@xenova/transformers';
let model, processor = null;

const isLoading = ref(false);

onMounted(async () => {
  console.log(111111111);

  // Since we will download the model from the Hugging Face Hub, we can skip the local model check
  env.allowLocalModels = false;
  env.remoteHost = "http://localhost:8080/models";
  // Proxy the WASM backend to prevent the UI from freezing
  env.backends.onnx.wasm.proxy = true;
  // Reference the elements that we will need
  //  Load model and processor
  isLoading.value = true

  model = await AutoModel.from_pretrained('', {
    // Do not require config.json to be present in the repository
    config: { model_type: 'custom' },
  });

  processor = await AutoProcessor.from_pretrained('', {
    // Do not require config.json to be present in the repository
    config: {
      do_normalize: true,
      do_pad: false,
      do_rescale: true,
      do_resize: true,
      image_mean: [0.5, 0.5, 0.5],
      feature_extractor_type: "ImageFeatureExtractor",
      image_std: [1, 1, 1],
      resample: 2,
      rescale_factor: 0.00392156862745098,
      size: { width: 1024, height: 1024 },
    }
  });
  isLoading.value = false
  document.body.style.backgroundColor = 'green'
})

/* // 文件选择后的事件
const handler = (e) => {
  const file = e;
  if (!file) {
    return;
  }
  const reader = new FileReader();
  // Set up a callback when the file is loaded
  reader.onload = e2 => predict(e2.target.result);
  reader.readAsDataURL(file);
}
 */

// Predict foreground of the given image
// 一寸照片标准尺寸：25×35mm，二寸照片标准尺寸：35×49mm
// 这里我们使用像素值，假设1mm≈3.78像素
async function predict(url, color, size = '1x1') {

  // Read image
  const image = await RawImage.fromURL(url);
  isLoading.value = true
  // Update UI
  // Set container width and height depending on the image aspect ratio
  const ar = image.width / image.height;
  const [cw, ch] = (ar > 720 / 480) ? [720, 720 / ar] : [480 * ar, 480];

  // Preprocess image
  const { pixel_values } = await processor(image);

  // Predict alpha matte
  const { output } = await model({ input: pixel_values });

  // Resize mask back to original size
  const mask = await RawImage.fromTensor(output[0].mul(255).to('uint8')).resize(image.width, image.height);

  // Create new canvas
  const canvas = document.createElement('canvas');
  const backgroundCanvas = document.createElement('canvas');

  canvas.width = image.width;
  canvas.height = image.height;
  // 根据尺寸参数设置canvas尺寸
  

  backgroundCanvas.width = image.width;
  backgroundCanvas.height = image.height;
  const ctx = canvas.getContext('2d');
  const bgCtx = backgroundCanvas.getContext('2d');

  // Draw original image output to canvas
  ctx.drawImage(image.toCanvas(), 0, 0);

  console.log(mask, 'mask')

  // Update alpha channel
  const pixelData = ctx.getImageData(0, 0, image.width, image.height);
  for (let i = 0; i < mask.data.length; ++i) {
    pixelData.data[4 * i + 3] = mask.data[i];
  }
  ctx.putImageData(pixelData, 0, 0);
  isLoading.value = false
  console.log(canvas, 'canvas');



  const targetColor = color; // 要替换的目标颜色（可改为任意颜色）
  // 绘制纯色背景
  bgCtx.fillStyle = targetColor;
  bgCtx.fillRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);

  // 将处理后的图像（带透明区域）缩放后叠加到纯色背景上
  // 计算缩放比例以适应目标尺寸
  const scaleX = backgroundCanvas.width / canvas.width;
  const scaleY = backgroundCanvas.height / canvas.height;
  const scale = Math.min(scaleX, scaleY);

  // 计算居中绘制的位置
  const x = (backgroundCanvas.width - canvas.width * scale) / 2;
  const y = (backgroundCanvas.height - canvas.height * scale) / 2;

  // 绘制缩放后的图像
  bgCtx.drawImage(canvas, x, y, canvas.width * scale, canvas.height * scale);

  // 现在backgroundCanvas就是带指定背景色的结果
  // 可以将其用于显示或进一步处理
  // document.body.appendChild(backgroundCanvas); // 示例：添加到页面

  return backgroundCanvas

  // Update UI
  /*  imageContainer.append(canvas);
   imageContainer.style.removeProperty('background-image');
   imageContainer.style.background = 'red';
   status.textContent = '完成!'; */
}
</script>

<style scoded>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-family: sans-serif;
}

html,
body {
  height: 100%;
}

body {
  padding: 16px 32px;
}

body,
#container,
#upload-button {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

h1 {
  text-align: center;
}

#container {
  position: relative;
  width: 640px;
  height: 420px;
  max-width: 100%;
  max-height: 100%;
  border: 2px dashed #d1d5db;
  border-radius: 0.75rem;
  overflow: hidden;
  margin-top: 1rem;
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
}

#mask-output {
  position: absolute;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

#upload-button {
  gap: 0.4rem;
  font-size: 18px;
  cursor: pointer;
}

#upload {
  display: none;
}

svg {
  pointer-events: none;
}

#example {
  font-size: 14px;
  text-decoration: underline;
  cursor: pointer;
}

#example:hover {
  color: #2563eb;
}

canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}

#status {
  min-height: 16px;
  margin: 8px 0;
  width: 640px;
}

input[type='range'] {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
}

.flex {
  display: flex;
  flex-direction: column;
  align-items: center;
}


/* loading 样式 */
.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-top-color: #000;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
